<template>
  <div class="editor-wrap">
    <div
      class="edit"
      :ref="'edit_' + BlocksIndex"
      :name="'edit_' + BlocksIndex"
      :type="type"
      :html="value"
      :BlocksIndex="BlocksIndex"
      contenteditable="true"
      :placeholder="
        type == 'hint' ? `输入需要重要提示的内容` : `输入 ' / ' 快速插入内容`
      "
    ></div>
  </div>
</template>

<script>
var _this = null;
export default {
  props: {
    value: {
      type: String,
      default: "",
    },
    text: {
      type: String,
      default: "",
    },
    type: {
      type: String,
    },
    BlocksIndex: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      isEmptyDelete: true, // 是否删除块
      range: null, // 光标
      currIndex: -1, // 当前index
      position: {
        // 样式bar位置
        left: 0,
        top: 0,
      },
    };
  },
  watch: {
    value: {
      handler(val) {
        this.addEmptyClass();
        let currEdit = this.$refs["edit_" + this.BlocksIndex];
        currEdit.innerHTML = val || "";
        // if (
        //   currEdit.innerHTML != "" &&
        //   currEdit.innerText != "" &&
        //   currEdit.innerText != "\n"
        // )
        //   this.$nextTick(() => {
        //     this.range.selectAllChildren(currEdit);
        //     this.range.collapseToEnd(); //光标移至最后
        //   });
      },
      deep: true,
    },
    currIndex(val) {
      this.$store.commit("mutationCurrentBlockIndex", val);
    },
  },
  computed: {
    currentPageBlocks() {
      return this.$store.state.currentPageBlocks;
    },
  },
  created() {},
  mounted() {
    _this = this;
    var currEdit = null;
    this.range = window.getSelection(); //创建range
    currEdit = this.$refs["edit_" + this.BlocksIndex];
    currEdit.innerHTML = this.value || "";
    document.execCommand("enableObjectResizing", false, true); // 启用图像大小可调整手柄

    // 鼠标按下事件 =》选中文字
    currEdit.onmousedown = (e) =>
      _this.mousedown(e, eval(currEdit.getAttribute("BlocksIndex")));
    // 鼠标弹起事件 =》选中文字
    currEdit.onmouseup = (e) =>
      _this.mouseup(e, eval(currEdit.getAttribute("BlocksIndex")));
    //键盘按下事件
    currEdit.onkeydown = (e) =>
      _this.keydown(e, eval(currEdit.getAttribute("BlocksIndex")));
    //键盘弹起事件
    currEdit.onkeyup = (e) =>
      _this.keyup(e, eval(currEdit.getAttribute("BlocksIndex")));

    currEdit.onblur = (e) =>
      _this.blur(e, eval(currEdit.getAttribute("BlocksIndex")));

    this.addEmptyClass();
  },
  methods: {
    // 添加/删除 类名
    addEmptyClass() {
      let dom = document.getElementsByClassName("edit");
      for (let i = 0; i < dom.length; i++) {
        let currEdit = dom[i],
          type = currEdit.getAttribute("type");
        if (
          (currEdit.innerHTML == "" ||
            currEdit.innerText == "" ||
            currEdit.innerText == "\n") &&
          type != "image" &&
          type != "video"
        ) {
          currEdit.classList.add("empty");
        } else {
          currEdit.classList.remove("empty");
        }
      }
    },
    // 块类型
    changeType(e) {
      let el = this.getEditElement(e);
      if (el) var type = el.getAttribute("type");
      switch (type) {
        case "heading1":
          document.execCommand("formatblock", false, "h1");
          break;
        case "heading2":
          document.execCommand("formatblock", false, "h2");
          break;
        case "heading3":
          document.execCommand("formatblock", false, "h3");
          break;
        default:
          document.execCommand("formatblock", false, "div");
          break;
      }
    },
    // 获取edit目标元素
    getEditElement(el) {
      if (el.className == "edit" || el.className == "edit empty") {
        return el;
      } else {
        if (el.parentElement) {
          return this.getEditElement(el.parentElement);
        } else {
          return {};
        }
      }
    },
    // 鼠标按下
    mousedown(e, index) {
      this.currIndex = index;
      this.position.left = e.pageX;
      this.position.top = e.pageY;
      this.$store.commit("mutationIsShowStyleBar", false); // 不显示样式bar
      // 是否点击图片或视频
      if (e.target.nodeName == "IMG" || e.target.nodeName == "VIDEO") {
        this.$store.commit("mutationisShowFileSize", true);
      } else {
        this.$store.commit("mutationisShowFileSize", false);
      }
    },
    // 鼠标弹起
    mouseup(e, index) {
      this.currIndex = index;
      if (e.pageX < this.position.left) this.position.left = e.pageX;
      if (e.pageY < this.position.top) this.position.top = e.pageY;
      let chooseContent = window.getSelection().toString(); // 选中内容
      if (chooseContent.length > 0) {
        this.$store.commit("mutationStyleBarContentLayerXY", this.position);
        setTimeout(() => {
          this.$store.commit("mutationIsShowStyleBar", true);
        }, 50);
      } else {
        this.$store.commit("mutationIsShowStyleBar", false);
      }
    },
    // 键盘按下
    keydown(e, index) {
      this.currIndex = index;
      let dom = document.getElementsByClassName("edit"),
        currEdit = dom[index];

      // enter
      if (e.keyCode == 13) {
        e.preventDefault();
        let addBlockInfo = {
          index: index,
          blockItem: {
            type: "text",
            data: {
              html: "",
              text: "",
            },
          },
        };
        e.preventDefault();
        // 提交数据到vuex
        this.$store.commit("mutationAddCurrentPageBlocks", addBlockInfo);
      }

      // 如果内容为空的时候，并且按了 '/ '号按钮，就可以唤醒键盘上的添加内容的弹窗
      if (
        (e.keyCode == 191 || e.keyCode == 111) &&
        (currEdit.innerHTML == "" ||
          currEdit.innerText == "" ||
          currEdit.innerText == "\n")
      ) {
        currEdit.setAttribute("contenteditable", false);
        let e = currEdit.getBoundingClientRect(),
          a = { x: e.left - 48, y: e.top };
        this.$store.commit("mutationAddMenuContentLayerXY", a);
        this.$store.commit("mutationCurrentBlockIndex", index);
        setTimeout(() => {
          this.$store.commit("mutationIsShowAddMenu", true);
        }, 50);
        currEdit.setAttribute("contenteditable", true);
      }
    },
    // 键盘弹起
    keyup(e, index) {
      this.addEmptyClass();
      this.changeType(e.target);
      this.currIndex = index;
      let dom = document.getElementsByClassName("edit"),
        currEdit = dom[index],
        type = currEdit.getAttribute("type"),
        nextEdit = dom[index + 1],
        lastEdit = dom[index - 1];

      // enter
      if (e.keyCode == 13) {
        e.preventDefault();
        nextEdit.focus();
        this.range.selectAllChildren(nextEdit);
        this.range.collapseToEnd(); //光标移至最后
      }

      // 上移
      if (e.keyCode == 38) {
        if (lastEdit) {
          lastEdit.focus();
          this.range.selectAllChildren(lastEdit);
          this.range.collapseToEnd(); //光标移至最后
          this.currIndex = index - 1;
        }
      }
      // 下移
      if (e.keyCode == 40) {
        if (nextEdit) {
          nextEdit.focus();
          this.range.selectAllChildren(nextEdit);
          this.range.collapseToEnd(); //光标移至最后
          this.currIndex = index + 1;
        }
      }
      // delete clear 删除
      if (e.keyCode == 46 || e.keyCode == 8) {
        if (
          (currEdit.innerHTML == "" ||
            currEdit.innerText == "" ||
            currEdit.innerText == "\n") &&
          this.currentPageBlocks.length > 1 &&
          this.isEmptyDelete == true
        ) {
          this.currentPageBlocks.splice(index, 1);
          setTimeout(() => {
            lastEdit.focus();
            this.range.selectAllChildren(lastEdit);
            this.range.collapseToEnd(); //光标移至最后
          }, 300);
        }
      }
      if (
        currEdit.innerHTML == "" ||
        currEdit.innerText == "" ||
        currEdit.innerText == "\n"
      ) {
        this.isEmptyDelete = true;
      } else {
        this.isEmptyDelete = false;
      }

      // // 回退
      // if (e.ctrlKey == true && e.keyCode == 90) {
      //   document.execCommand("undo");
      // }

      // // 修改--> 不为 enter 上移 下移键 删除块
      // if (
      //   e.keyCode != 13 &&
      //   e.keyCode != 38 &&
      //   e.keyCode != 40 &&
      //   this.isEmptyDelete == false
      // ) {
      //   if (type == "heading1" || type == "heading2" || type == "heading3") {
      //     this.update(index);
      //   }
      // }
    },
    // 失焦-->修改保存
    blur(e, index) {
      this.update(index);
    },
    // 修改块
    update(index) {
      let dom = document.getElementsByClassName("edit"),
        currEdit = dom[index],
        editable = eval(currEdit.getAttribute("contenteditable")),
        type = currEdit.getAttribute("type");
      // 可编辑
      if (editable) {
        console.log(
          "修改----",
          "type---:",
          type,
          "index---:",
          index,
          "innerHTML---:",
          currEdit.innerHTML
        );
        if (currEdit.innerText.length > 0) {
          let blockInfo = {
            index: index,
            blockItem: {
              type: type,
              data: {
                html: currEdit.innerHTML,
                text: currEdit.innerText,
              },
            },
          };
          // 提交数据到vuex
          this.$store.commit("mutationUpdateCurrentPageBlocks", blockInfo);
        }
      }
    },
  },
  beforeDestroy() {},
};
</script>

<style lang="less">
h1,
h2,
h3 {
  margin: 0 !important;
}
.editor-wrap {
  width: 100%;
  height: auto;
  cursor: text;
  .edit {
    min-height: 30px;
    height: auto;
    line-height: 2;
    width: 100%;
    overflow-y: scroll;
    position: relative;
    outline: none !important;
    // -webkit-user-modify: read-write-plaintext-only;
    // -webkit-user-modify: read-write;
    &::-webkit-scrollbar {
      display: none;
    }
    &::selection {
      background: #b9dcea;
      color: #000;
    }
    &::-moz-selection {
      background: #b9dcea;
      color: #000;
    }
    &::-webkit-selection {
      background: #b9dcea;
      color: #000;
    }
  }
  .edit.empty:focus {
    padding: 0;
    &::before {
      height: 100%;
      display: flex;
      align-items: center;
      font-size: inherit;
      z-index: 999 !important;
      position: absolute;
      content: attr(placeholder);
      color: #999;
      padding-left: 5px;
    }
  }
}
</style>